package frame.util;

import java.util.List;

// 处理byte数组的工具类
public class ByteArrayUtil {

    // 将byte数组转化为无符号意义下的int数组
    public static int[] toUnsignedIntArray(byte[] bs) {

        int[] tmp = new int[bs.length];

        for(int i = 0; i < tmp.length; ++i) tmp[i] = Byte.toUnsignedInt(bs[i]);

        return tmp;
    }

    // 将byte数组转化为对应的16进制数字字符串
    public static String toHexString(byte[] bs) {

        StringBuilder sb = new StringBuilder();

        for(byte b : bs) {

            String tmp = Integer.toHexString(Byte.toUnsignedInt(b));

            if(tmp.length() == 1) sb.append("0");

            sb.append(tmp);
        }

        return sb.toString();
    }

    // 将short数组转化为对应的16进制数字字符串
    public static String toHexString(short[] ss) {

        StringBuilder sb = new StringBuilder();

        for(short s : ss) {

            String tmp = Integer.toHexString(Short.toUnsignedInt(s));

            for(int l = tmp.length(); l < 4; ++l) sb.append("0");

            sb.append(tmp);
        }

        return sb.toString();
    }

    // 将int数组转化为对应的16进制数字字符串
    public static String toHexString(int[] is) {

        StringBuilder sb = new StringBuilder();

        for(int i : is) {

            String tmp = Long.toHexString(Integer.toUnsignedLong(i));

            for(int l = tmp.length(); l < 8; ++l) sb.append("0");

            sb.append(tmp);
        }

        return sb.toString();
    }

    // 将16进制字符串解析为对应的byte数组
    public static byte[] hexStringToBytes(String hex) {

        byte[] ret = new byte[hex.length() / 2];

        for(int i = 0, j = 1; i < hex.length() && j < hex.length(); i += 2, j += 2) {

            ret[i >>> 1] = (byte) Short.parseShort("" + hex.charAt(i) + hex.charAt(j), 16);
        }

        return ret;
    }

    // 将byte数组解析为ASCII字符串 每一位对应一个字符
    public static String toAsciiString(byte[] bs) {

        StringBuilder sb = new StringBuilder();

        for(int b : bs) sb.append((char) b);

        return sb.toString();
    }

    // 将ASCII字符串解析为对应的byte数组 每个字符占用一个字节
    public static byte[] asciiStringToBytes(String ascii) {

        byte[] tmp = new byte[ascii.length()];

        for(int i = 0; i < tmp.length; ++i) {

            tmp[i] = (byte) ascii.charAt(i);
        }

        return tmp;
    }

    // 连接2个byte数组
    public static byte[] concat(byte[] a, byte[] b) {

        if(a == null) return b;

        if(b == null) return a;

        byte[] tmp = new byte[a.length + b.length];

        System.arraycopy(a, 0, tmp, 0, a.length);

        System.arraycopy(b, 0, tmp, a.length, b.length);

        return tmp;
    }

    // 连接多个byte数组 使用变长参数
    public static byte[] concat(byte[] a, byte[] ... bss) {

        byte[] tmp = new byte[flattenArrayLength(bss) + a.length];

        System.arraycopy(a, 0, tmp, 0, a.length);

        for(int i = 0, pos = a.length; i < bss.length; pos += bss[i].length, ++i) {

            System.arraycopy(bss[i], 0, tmp, pos, bss[i].length);
        }

        return tmp;
    }

    // 将一个容纳byte数组的列表摊平为一个byte数组
    public static byte[] flatten(List<byte[]> params) {

        byte[] tmp = new byte[flattenListLength(params)];

        for(int i = 0, pos = 0; i < params.size(); pos += params.get(i).length, ++i) {

            System.arraycopy(params.get(i), 0, tmp, pos, params.get(i).length);
        }

        return tmp;
    }

    // 获取二维byte数组的一维成员的总长度
    private static int flattenArrayLength(byte[][] arr) {

        int totalLength = 0;

        for (byte[] bs : arr) totalLength += bs.length;

        return totalLength;
    }

    // 获取容纳byte数组的列表中byte数组的总长度
    private static int flattenListLength(List<byte[]> list) {

        int totalLength = 0;

        for (byte[] bs : list) totalLength += bs.length;

        return totalLength;
    }

    // 手动拆箱
    public static byte[] unBoxed(Byte[] bs) {

        byte[] tmp = new byte[bs.length];

        for(int i = 0; i < tmp.length; ++i) tmp[i] = bs[i];

        return tmp;
    }

    // 使用变长参数方式构造byte数组
    public static byte[] asByteArray(byte ... bs) {

        return bs;
    }
}
